package cn.yh.register.user.service.impl;
import java.util.Date;

import cn.yh.register.client.cmn.CmnFeignClient;
import cn.yh.register.common.helper.JwtHelper;
import cn.yh.register.enums.AuthStatusEnum;
import cn.yh.register.model.user.Patient;
import cn.yh.register.user.service.PatientService;
import cn.yh.register.vo.user.UserAuthVo;
import cn.yh.register.vo.user.UserInfoQueryVo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;

import cn.yh.register.common.exception.RegisterException;
import cn.yh.register.common.result.ResultCodeEnum;
import cn.yh.register.model.user.UserInfo;
import cn.yh.register.user.mapper.UserInfoMapper;
import cn.yh.register.user.service.UserInfoService;
import cn.yh.register.vo.user.LoginVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {


    @Autowired
    private RedisTemplate<String ,String> redisTemplate;

    @Autowired
    private CmnFeignClient cmnFeignClient;

    @Autowired
    private PatientService patientService;

    /**
     * 用户登录功能
     * @param loginVo 封装的登录
     * @return 用户信息
     */
    @Override
    public Map<String, Object> login(LoginVo loginVo) {
        //取手机号
        String phone = loginVo.getPhone();
        //取验证码
        String code = loginVo.getCode();
        //校验手机号和验证码是否为空
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
            //为空 抛异常
            throw new RegisterException(ResultCodeEnum.PARAM_ERROR);
        }
        //校验验证码
        //从redis中取
        String cacheCode = redisTemplate.opsForValue().get(phone);
        //进行比较
        if (!code.equalsIgnoreCase(cacheCode)){
            throw new RegisterException(ResultCodeEnum.CODE_ERROR);
        }
        //不为空 根据手机号查询用户是否注册过
        UserInfo userInfo = baseMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getPhone, phone));
        //没有注册过 直接新注册一个用户
        if (null == userInfo){
            //注册新用户
            userInfo = new UserInfo();
            userInfo.setPhone(phone);
            userInfo.setAuthStatus(0); // 0 表示未认证
            userInfo.setStatus(1); //1 表示正常状态
            baseMapper.insert(userInfo);
        }

        // TODO 把用户登录的记录存到user_login_record表

         //已注册  直接登录  但需要判断是否可用
        if (userInfo.getStatus() == 0) {
            throw new RegisterException(ResultCodeEnum.LOGIN_DISABLED_ERROR);
        }

        //处理name信息  返回给前端显示的
        String name = userInfo.getName();
        if (StringUtils.isEmpty(name)) {
            name = userInfo.getNickName();
        }
        if (StringUtils.isEmpty(name)){
            name = userInfo.getPhone();
        }

        //封装登录信息
        Map<String,Object> map = new HashMap<>();
        //生成token
        String token = JwtHelper.createToken(userInfo.getId(), name);
        map.put("name",name);
        map.put("token", token);
        //返回
        return map;
    }

    /**
     * 用户认证功能 本质是用户修改一下信息
     *
     * @param userId     用户id
     * @param userAuthVo 封装的用户提交的东西
     */
    @Override
    public void userAuth(Long userId, UserAuthVo userAuthVo) {
        //先根据id查出来用户信息
        UserInfo userInfo = baseMapper.selectById(userId);
        //判断
        if (userInfo != null){
            BeanUtils.copyProperties(userAuthVo,userInfo);
            userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());
            baseMapper.updateById(userInfo);
        }
    }

    /**
     * 获取认证人的用户信息
     * @param userId 用户id
     * @return 用户信息
     */
    @Override
    public UserInfo getUserInfo(Long userId) {
        UserInfo userInfo = baseMapper.selectById(userId);
        //对信息做个处理
        this.packUserInfo(userInfo);
        return userInfo;
    }

    /**
     * 分页查询用户列表
     *
     * @param page    当前页
     * @param size    当前页大小
     * @param queryVo 封装查询条件
     * @return 用户信息
     */
    @Override
    public Page<UserInfo> findPageList(Integer page, Integer size, UserInfoQueryVo queryVo) {
//     page对象
        Page<UserInfo> p = new Page<>(page, size);
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<UserInfo>();
        wrapper.like(!StringUtils.isEmpty(queryVo.getKeyword()),UserInfo::getName,queryVo.getKeyword())
                .or()
                .like(!StringUtils.isEmpty(queryVo.getKeyword()),UserInfo::getPhone,queryVo.getKeyword())
                //用户状态
                .eq(!StringUtils.isEmpty(queryVo.getStatus()),UserInfo::getStatus,queryVo.getStatus())
                //认证状态
                .eq(!StringUtils.isEmpty(queryVo.getAuthStatus()),UserInfo::getAuthStatus,queryVo.getAuthStatus())
                //创建时间
                .ge(!StringUtils.isEmpty(queryVo.getCreateTimeBegin()),UserInfo::getCreateTime,queryVo.getCreateTimeBegin())
                .le(!StringUtils.isEmpty(queryVo.getCreateTimeEnd()),UserInfo::getCreateTime, queryVo.getCreateTimeEnd());
       //分页查询
        Page<UserInfo> userInfoPage = baseMapper.selectPage(p, wrapper);
        //获取数据
        userInfoPage.getRecords().forEach(this::packUserInfo);
        return userInfoPage;
    }

    /**
     * 用户锁定/解锁
     *
     * @param userId 用户id
     * @param status 0：锁定  1：正常
     */
    @Override
    public void lock(Long userId, Integer status) {
        if (status.intValue() ==0 || status.intValue() ==1){
            UserInfo userInfo = this.getById(userId);
            userInfo.setStatus(status);
            this.updateById(userInfo);
        }
    }

    /**
     * 后台系统获取用户信息
     *
     * @param userId 用户id
     * @return 用户信息
     */
    @Override
    public Map<String, Object> getUser(Long userId) {
        //用户详情信息
        UserInfo userInfo = baseMapper.selectById(userId);
        this.packUserInfo(userInfo);
        //就诊人信息
        List<Patient> patientList = patientService.findByUserId(userId);
        //存入map中返回
        HashMap<String,Object> map = new HashMap<>();
        map.put("userInfo",userInfo);
        map.put("patientList",patientList);
        return map;
    }

    /**
     * 用户列表审批
     *
     * @param userId     认证审批
     * @param authStatus 2：通过，-1：不通过
     */
    @Override
    public void approve(Long userId, Integer authStatus) {
        if (authStatus ==2 || authStatus == -1 ) {
            UserInfo userInfo = baseMapper.selectById(userId);
            userInfo.setAuthStatus(authStatus);
            baseMapper.updateById(userInfo);
        }
    }

    /**
     * 用户信息处理
     * @param userInfo 用户信息
     */
    private void packUserInfo(UserInfo userInfo) {
        //证件类型
        if (!StringUtils.isEmpty(userInfo.getCertificatesType())){
            //根据数字编码获取名称
            String certificatesTypeString = cmnFeignClient.getName(userInfo.getCertificatesType());
//            String certificatesTypeString = cmnFeignClient.getName(userInfo.getCertificatesType());
            userInfo.getParam().put("certificatesTypeString",certificatesTypeString);
        }
        //认证状态
        String authStatusString = AuthStatusEnum.getStatusNameByStatus(userInfo.getAuthStatus());
        userInfo.getParam().put("authStatusString",authStatusString);

    }
}
